package modele;

import java.util.ArrayList;


/**
 * @author shaance
 */
public class Player implements Comparable<Player> {

    /**
     * The player's username
     */
    private String username;

    /**
     * The player's highest score
     */
    private int highScore = 0;

    /**
     * All the scores of the player
     */
    private ArrayList<String> scoreHistory;

    /**
     * The player's current winning streak
     */
    private int winningStreak;

    /**
     * The player's current losing streak
     */
    private int losingStreak;

    /**
     * The player's ranking among the other players
     */
    private int ranking;
    private static int playerCount = 1;

    /**
     * Constructor without parameter
     */
    public Player() {
        this.username = "Player" + playerCount;
        playerCount++;
    }

    /**
     * Constructor with parameter
     *
     * @param username the username you want to set
     */
    public Player(String username) {
        if (username == null) {
            throw new NullPointerException();
        }
        this.username = username;
        playerCount++;
    }

    /**
     * Getter of the username attribute
     *
     * @return player's username
     */
    public String getUsername() {
        return this.username;
    }

    /**
     * Setter of the username attribute
     *
     * @param username the username you want to set
     */
    public void setUsername(String username) {
        this.username = username;
    }

    /**
     * Getter of the highScore attribute
     *
     * @return the player's highest score
     */
    public int getHighScore() {
        return this.highScore;
    }

    /**
     * Setter of the highScore attribute
     *
     * @param highScore the highScore to set
     */
    public void setHighScore(int highScore) {
        this.highScore = highScore;
    }

    /**
     * Getter of the scoreHistory attribute
     *
     * @return all the player's scores
     */
    public ArrayList<String> getScoreHistory() {
        return new ArrayList<>(scoreHistory);
    }

    /**
     * Getter of winningStreak attribute
     *
     * @return player's winning streak
     */
    public int getWinningStreak() {
        return this.winningStreak;
    }

    /**
     * Getter of the losingStreak attribute
     *
     * @return player's losing streak
     */
    public int getLosingStreak() {
        return this.losingStreak;
    }

    /**
     * Getter of the ranking attribute
     *
     * @return player's ranking
     */
    public int getRanking() {
        return this.ranking;
    }

    /**
     * Setter of the scoreHistory attribute
     *
     * @param scoreHistory player's all scores
     */
    public void setScoreHistory(ArrayList<String> scoreHistory) {
        this.scoreHistory = new ArrayList<>(scoreHistory);
    }

    /**
     * Setter of the winningStreak attribute
     *
     * @param winningStreak player's current winning streak
     */
    public void setWinningStreak(int winningStreak) {
        this.winningStreak = winningStreak;
    }

    /**
     * Setter of the losingStreak attribute
     *
     * @param losingStreak player's current losing streak
     */
    public void setLosingStreak(int losingStreak) {
        this.losingStreak = losingStreak;
    }

    /**
     * Setter of the ranking attribute
     *
     * @param ranking player's current ranking
     */
    public void setRanking(int ranking) {
        this.ranking = ranking;
    }

    /**
     * Method to add a score into the scoreHistory attribute
     *
     * @param score the score you want to store
     */
    public void addScore(String score) {
        scoreHistory.add(score);
    }

    /**
     * Method to remove a specific score at a specific index
     *
     * @param index index at which you want a score to be removed
     */
    public void removeScoreAt(int index) {
        scoreHistory.remove(index);
    }

    /**
     * Method to clear all the stored scores
     */
    public void clearScoreHistory() {
        scoreHistory.clear();
    }

    /**
     * Method to increase player's winning streak
     */
    public void increaseWinningStreak() {
        winningStreak++;
    }


    /**
     * Method to increase player's losing streak
     */
    public void increaseLosingStreak() {
        losingStreak++;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Player player = (Player) o;

        if (highScore != player.highScore) return false;
        if (losingStreak != player.losingStreak) return false;
        if (ranking != player.ranking) return false;
        if (winningStreak != player.winningStreak) return false;
        if (scoreHistory != null ? !scoreHistory.equals(player.scoreHistory) : player.scoreHistory != null)
            return false;
        return !(username != null ? !username.equals(player.username) : player.username != null);

    }

    @Override
    public int hashCode() {
        int result = username != null ? username.hashCode() : 0;
        result = 31 * result + highScore;
        result = 31 * result + (scoreHistory != null ? scoreHistory.hashCode() : 0);
        result = 31 * result + winningStreak;
        result = 31 * result + losingStreak;
        result = 31 * result + ranking;
        return result;
    }

    @Override
    public String toString() {
        final StringBuilder sb = new StringBuilder("Player{");
        sb.append("username='").append(username).append('\'');
        sb.append(", highScore=").append(highScore);
        sb.append(", winningStreak=").append(winningStreak);
        sb.append(", losingStreak=").append(losingStreak);
        sb.append(", ranking=").append(ranking);
        sb.append('}');
        return sb.toString();
    }

    @Override
    public int compareTo(Player o) {
        if (o == null) return 1;
        if (highScore > o.highScore) return 1;
        if (highScore < o.highScore) return -1;
        else return 0;
    }
}
